/*
TategumiCore.js
	Javascript Class,using Mootools(http://mootools.net/).
	Convert horizontal line layout to top-to-bottom and left-to-right,Japanese line layout.


Licence:
	MIT-style licence.

SupportBrowser:
	IE7+,Safari3,Firefox3,Chrome

Copyright(c)2009
MASAKI YAMABE @ALLIANCE PORT, LLC.
AKIHIKO TOMOKANE

*/
var BROWSER = {
	'engine': Browser.Engine.name,
	'version': Browser.Engine.version
};

if (BROWSER.engine == 'gecko') {
	var ffVer = navigator.userAgent;
	//Firefox 3.1 beta or higher is true.3.0.x is false.
	var FF_ROTATE_ENABLE = ffVer.substr(ffVer.indexOf('Firefox') + 8, 3).toFloat() > 3.0;
}

//need make adjustment position characters.
var SMALL_CHARACTERS = ['ぁ','ぃ','ぅ','ぇ','ぉ','ァ','ィ','ゥ','ェ','ォ','っ','ッ','ゃ','ゅ','ょ','ャ','ュ','ョ'];
var PUNCTUATION_MARKS = ['、','。'];

//need replace or rotate 90 degrees charagters.
var NEED_ROTATE_MARKS = {
	'（': '︵',
	'）': '︶',
	'｛': '︷',
	'｝': '︸',
	'「': '﹁',
	'」': '﹂',
	'『': '﹃',
	'』': '﹄',
	'ー': '︱',
	'…': '︰',
	'(': '︵',
	')': '︶',
	'{': '︷',
	'}': '︸',
	'[': '︵',
	']': '︶',
	'【': '︵',
	'】': '︶',
	
	//need discussion.
	'〔': '︵',
	'〕': '︶',
	'〈': '︵',
	'〉': '︶',
	'《': '︵',
	'》': '︶',
	'〘': '︵',
	'〙': '︶',
	'〖': '︵',
	'〗': '︶',
	'〝': '﹃',
	'〟': '﹄',
	'‘': '﹁',
	'’': '﹂',
	'“': '﹃',
	'”': '﹄',
	'｟': '︵',
	'｠': '︶',
	'«': '︵',
	'»': '︶'
};

//need handling kinsoku characters,biginning of line.
var BEGINNING_KINSOKU_CHARACTERS = ['︶','︸','﹂','﹄','︱','︰','︸',',',')',']','｝','、','〕','〉','》','」','』','】','〙','〗','〟','’','”','｠','»','ヽ','ヾ','ー','ァ','ィ','ゥ','ェ','ォ','ッ','ャ','ュ','ョ','ヮ','ヵ','ヶ','ぁ','ぃ','ぅ','ぇ','ぉ','っ','ゃ','ゅ','ょ','ゎ','ゕ','ゖ','ㇰ','ㇱ','ㇲ','ㇳ','ㇴ','ㇵ','ㇶ','ㇷ','ㇸ','ㇹ','ㇺ','ㇻ','ㇼ','ㇽ','ㇾ','ㇿ','々','〻','‐','゠','–','〜','?','!','‼','⁇','⁈','⁉','・',':',';','。','.'];


var TategumiCore = new Class({
	Implements: Options,
	
	/*
	 * options: optional styles
	 * 
	 */
	options: {
		fontSize: '12px',
		lineHeight: '15px',
		letterSpacing: '15px',
		textAlign: 'justification',
		textAlignLast: 'top',
		textIndent: '15px',
		columnMargin: '15px'
	},
	
	/*
	 * constructor: initialize
	 * 
	 * arguments:
	 * 	source(strings(html)):source of convert paragraph.
	 * 	charactersPerColumn(int):max characters into a column.using a calculation the height of destination box element.
	 */
	initialize: function(source,charactersPerColumn,options){
		this.setOptions(options);
		
		this.source = source;
		this.charactersPerColumn = charactersPerColumn;
		
		this.castSource = [];
		
		this.destEl = new Element('p');
		
		this.getIncludedElements();
		
		
	},
	
	injectParagraph: function(el){
		this.destEl.inject(el)
	},
	
	getStyles: function(){
		
	},
	
	setStyles: function(){
		
	},
	
	/*
	 * 
	 */
	getIncludedElements: function(){
		
		var count = 0;
		var tag = '';
		var isTag = false;
		
		var tagPeriod = 0;
		
		for(var index = 0;index < this.source.length;index++){
			var item = this.source.charAt(index);
			if (isTag) {//add html tag include source to before character.
				
				if(item == '>') {
					tag = tag + item;
					if(!tagPeriod)this.castSource[count-1].tag = tag;
					else this.castSource[count-1].tag = 'end';
					isTag = false;
					tagPeriod = (tagPeriod + 1) % 2;
				}
				else{
					tag = tag + item;
				}
			}
			else {
				if (item == '<') {
					isTag = true;
					tag = item;
				}
				else {//judge character need replace or rotate.
					if(NEED_ROTATE_MARKS[item]){
						
						if(BROWSER.engine == 'gecko' && !FF_ROTATE_ENABLE)//replace character when used not suport rotate stylesheet browser.need research.
							this.castSource.push({'character':NEED_ROTATE_MARKS[item]});
						else
							this.castSource.push({'character':item,'rotate':true});
					}
					else
						this.castSource.push({'character':item});
						
					count++;
				}
			}
		}
		
		this.setKINSOKU();
		
	},
	
	setKINSOKU: function(){
		
		for(i = this.charactersPerColumn - 1;i < this.castSource.length;i = i + this.charactersPerColumn){
			if (this.castSource[i + 1]) {
				if (BEGINNING_KINSOKU_CHARACTERS.contains(this.castSource[i + 1].character)) {
					this.castSource[i].lineBegin = true;
					i = i - 1;
				}
				else 
					this.castSource[i + 1].lineBegin = true;
			}
		}
		
		this.createParagraphEl();
	},
	
	rotationCharacter: function(el){
		if (BROWSER.engine == "webkit") {//safari and chrome
			el.setStyles({
				'-webkit-transform': 'rotate(90deg)'
			})
		}
		else if (BROWSER.engine == "trident") {//ie
			el.setStyles({
				'filter':'progid:DXImageTransform.Microsoft.basicimage(rotation=1)'
			})
		}
		else if (BROWSER.engine == "gecko") {//Firefox
			el.setStyles({
				'-moz-transform': 'rotate(90deg)',
				'-moz-transform-origin': 'center center'
			})
		}
	},
	
	replaceExceptionCharacter: function(){
		
	},
	
	createLineEl: function(castLineSource){
		
		var line = new Element('span').setStyles({
				'display': 'block',
				'float': 'right',
				'width': '1em',
				'height': (this.options.fontSize.toInt() * this.charactersPerColumn.toInt() + this.options.letterSpacing.toInt() * (this.charactersPerColumn.toInt() - 1)) + 'px',
				'padding-left': this.options.lineHeight,
				'padding-bottom':this.options.columnMargin
		});
		
		castLineSource.each(function(item,index){
			
			item.el = new Element('span').setStyles({
					'display': 'block',
					'width': this.options.fontSize,
					'height': this.options.fontSize,
					'text-align': 'center',
					'margin-bottom': this.options.letterSpacing
			})
			
			if(item.rotate) this.rotationCharacter(item.el);
			
			item.el.set('text',item.character).inject(line);
			
			this.setExceptionStyle(item.el);
			
		}.bind(this))
		
		line.inject(this.destEl)
		
	},
	
	createParagraphEl: function(){
		var lineEl = [];
		
		this.castSource.each(function(item,index){
			
			if(!item.lineBegin)
				lineEl.push(item);
			else{
				this.createLineEl(lineEl);
				lineEl = [item];
			}
				
		}.bind(this))
		this.createLineEl(lineEl);
	},

	setExceptionStyle: function(el){
		if(SMALL_CHARACTERS.contains(el.get('text'))){
			el.setStyles({
				'position': 'relative',
				'left': '0.2em',
				'bottom': '0.2em'
			});
		}
		
		if(PUNCTUATION_MARKS.contains(el.get('text'))){
			el.setStyles({
				'position': 'relative',
				'left': '0.7em',
				'bottom': '1.1em'
			});
		}
	},
	
	applyJustification: function(){
		
	},
	
	applyModification: function(){
		
	}
})
	